上一节 已经说了 AVL树的插入 操作,可是 只有 插入,没有删除,怎么能叫 动态 查找表呢。
呵呵,博主 赶紧 去 研究了一番。下面 是成果:
AVL树的删除 大致 分为 两大块: 1. 查找节点 并 删除 2. 保持 删除 后 平衡因子的 影响
1. 首先 找到 这个 节点,如果 节点 不存在,直接 退出 函数
if (*tree == NULL){//没找到
return false;
}
2.如果 存在,分为 四种情况:(根 二叉 排序树的 删除 类似)
1.节点 为 叶子 节点,直接 删除
2.节点 的 左子树为空,则 用 节点的 右子树 代替 节点,并删除 这个节点。
3.节点的 右子树为空,则用 节点的 左子树 代替节点,并 删除 这个 节点
4.左右子树 都不为空 (下面 这样做,是为了 减少 旋转的 次数 ,如果 不懂,请 往下看,看完,再回头看)
4.1 如果 节点的 左子树的高度 >= 右子树的高度(LH,EH),则 从 左子树里 寻找 值 最大节点,将最大值赋值 给 节点,并删除 最大节点。
4.2如果节点 的 左子树的高度 《 右子树的高度(RH),则从 右子树里 寻找 值 最小的节点,并将 最小值 赋值给 节点,并删除最小节点
if (data == key){
if (p->lChild == NULL){//叶子节点 或者 左孩子为空
*tree = p->rChild;//
free(p);
*shorter = true;
}
else if(p->rChild == NULL){//右子树为空
*tree = p->lChild;
free(p);
*shorter = true;
}
else{//左右子树 都不为空
if (p->bf == LH || p->bf == EH){//左高,或者等高,//从左子树里寻找 最大节点(左子树的 最右下角)
AvlTree lc = p->lChild;
while (lc->rChild != NULL){
lc = lc->rChild;
}
p->data = lc->data;//替换以后 ,然后删除 替换节点
//然后从 左子树里 寻找删除节点,并删除它.
deleteAvlTree(&p->lChild,p->data,shorter);
}
else{//右高,从 右子树里寻找 最小的 替换
AvlTree rc = p->rChild;
while (rc->lChild != NULL){
rc = rc->lChild;
}
p->data = rc->data;
//然后从 右子树里寻找删除节点,并